# coding:utf-8
# 战斗计算器

import glog, glb
import battle_skill_mgr

from glb import BATTLE_RESULT_WIN, BATTLE_RESULT_LOSE, BATTLE_RESULT_DRAW
from glb import BATTLE_DATA_EVENT_ATTACK, BATTLE_DATA_EVENT_MOVE
from glb import BATTLE_FRAME_PER_SECOND

# 一场战斗最大帧数 暂定1秒5帧 10分钟
MAX_FRAMES = 1*30*BATTLE_FRAME_PER_SECOND #10*60*BATTLE_FRAME_PER_SECOND


class BattleCalc():
	def __init__(self, matrix_a, matrix_b):
		self.ma = matrix_a
		self.mb = matrix_b
		self.log = {}
		self.result = -1


	def run(self):
		# 按照速度排序
		units = self.ma.units + self.mb.units
		units.sort(key=lambda x:x.spd, reverse=True)

		# 写入临时id
		for i in xrange(len(units)):
			u = units[i]
			u.id = i

		# 记录初始化信息
		self._create_init_data(units)

		frames_cnt = 0
		battle_data = {}	# 战斗数据
		is_exit = False
		while not is_exit:
			frames_cnt += 1
			frame_data = []	# 一帧的数据

			for u in units:
				if not u.is_alive(): continue

				u.move_cnt += 1
				u.attack_cnt += 1

				# 攻击
				is_attacked = False
				if u.attack_cnt >= u.attack_speed_frames:
					attack_data = self.attack(u)
					if attack_data:
						print '-- attack', frames_cnt, u.id
						is_attacked = True
						u.attack_cnt = 0	# 攻击成功才清理cd
						frame_data.append(attack_data)

				# 攻击过则不能移动 and 移动CD到 and 攻击不到目标
				if not (is_attacked or (u.move_cnt < u.move_speed_frames or u.move_speed_frames <= 0) or battle_skill_mgr.can_attack(u, self.ma, self.mb)):
					move_data = self.move(u)
					if move_data:
						print '-- move', frames_cnt, u.id
						u.move_cnt = 0 # 移动后清理cd
						frame_data.append(move_data)

			# 帧数据加入战斗数据
			if len(frame_data) > 0:
				battle_data[frames_cnt] = frame_data

			# 是否满足结束条件
			ma_all_dead = self.ma.is_all_dead()
			mb_all_dead = self.mb.is_all_dead()
			if ma_all_dead != mb_all_dead and ma_all_dead:
				self.result = BATTLE_RESULT_LOSE
				is_exit = True
			if ma_all_dead != mb_all_dead and mb_all_dead:
				self.result = BATTLE_RESULT_WIN
				is_exit = True
			if ma_all_dead == mb_all_dead and ma_all_dead:
				self.result = BATTLE_RESULT_DRAW
				is_exit = True
			# 时间到的情况
			if frames_cnt >= MAX_FRAMES:
				self.result = BATTLE_RESULT_DRAW
				is_exit = True

		# 战斗数据加入log
		self.log['battle'] = battle_data

		# 记录结算信息
		self._create_result_data()


	# 移动一次
	def move(self, unit):
		target_x = unit.x
		target_y = unit.y
		if unit.is_side_a(): target_x += 1
		else: target_x -= 1

		# 检查是否有人
		target_unit = self._get_unit_by_pos(target_x, target_y)
		if target_unit: return

		#print "move ======", unit.id, unit.x, unit.y, "->", target_x, target_y

		unit.move_step(target_x, target_y)
		move_data = [BATTLE_DATA_EVENT_MOVE, unit.id, unit.x, unit.y]
		return move_data


	def _get_unit_by_pos(self, x, y):
		res = self.ma.get_unit_by_pos(x, y)
		if res is None:
			res = self.mb.get_unit_by_pos(x, y)
		if res and res.is_alive():
			return res


	# 发动攻击
	def attack(self, unit):
		attack_data = None

		targets = battle_skill_mgr.get_attack_targets(unit, self.ma, self.mb)
		# 没有选中目标, 退出
		if len(targets) == 0: return

		# 计算伤害
		die_ids = []
		dmg = 0
		for t in targets:
			dmg = abs(unit.atk - unit.dfn)
			t.hp -= dmg
			# 卡片死亡
			if t.hp <= 0: die_ids.append(t.id)

		event_type = BATTLE_DATA_EVENT_ATTACK
		target_ids = [t.id for t in targets]
		attack_data = [event_type, unit.id, unit.skill,  dmg, target_ids, die_ids]
		return attack_data


	def _create_init_data(self, units):		
		units_data = []
		for u in units:
			data = [u.id, u.is_player, u.type, u.x, u.y]
			units_data.append(data)
			
		init_data = {'units' : units_data}
		self.log['init'] = init_data


	def _create_result_data(self):
		self.log['result'] = {'battle_result':self.result}




